<?

require_once('../config.inc.php');
require_once($config['app_dir']."/includes/db.class.php");
require_once($config['app_dir'] . '/includes/template.class.php');
require_once($config['app_dir'] . '/includes/session.class.php');
require_once($config['app_dir'] . '/includes/date.class.php');


class objCalculator {
	//allows only to create new or edit existing
	var $Years;
	var $cMonths;
	var $Months = array(1,2,3,4,5,6,7,8,9,10,11,12);
	var $test ='';
	var $dDate = array();
	var $pairsArr = array();
	var $fcastsArr = array();
	var $graphArr = array();
	var $graphArrDetailed = array();
	var $graphArrWeek = array();
	var $slippage;
	var $spreadArr;
	var $deposit;
	var $contract;
	var $trades;
	var $lossTrades = 0;
	var $winTrades = 0;
	var $tPips;
	var $tProfit;
	var $tBalance;
	var $tARR;
	var $tDdown = false;
	var $endMonth = array();



 		function __construct() {
			$this->db = objDataBase::GetInstance();//new objDataBase();
			$this->Years = $this->getYears();
      	} //constructor

        function getPairs() {
        	$pairsArr = array();
			$query = "SELECT * FROM fa_trades ORDER BY TradeID asc";

		try {
           $rs = $this->db->Execute($query);
	           if ($rs){
	           		$cnter=0;
					while (!$rs->EOF) {
						$this->pairsArr[]= array(
								'Pair' => $rs->fields['Pair'],
								'TradeID' => $rs->fields['TradeID'],
								'pUSD' => $rs->fields['PriceUSD'],
								'Spread' => $this->spreadArr[$cnter],
								'defSpread' => $rs->fields['DefaultSpread'],
								'pipSize' => $rs->fields['PipSize']
								);
						$this->test .= ' <br>';
						$cnter++;
				        $rs->MoveNext();
					}
				}


         } catch(exception $e) {
            if (true == $this->db->debug ) {
              adodb_pr($e);
              $e = adodb_backtrace($e->trace);
            }
            die('DB Error: '.$e->sql);
         }
            $this->pairsArr;
			return $this->pairsArr;
      	}

      	function getForecastData($date_from,$date_to,$pair_id,$selPairs) {
        	$fcastsItem = array();
        	$statsArr = array();
        	$balanceArr = array();
        	$currBalance = $this->deposit;
        	$maxbalance = $this->deposit;
        	$tPips = 0;
        	$tProfit = 0;
        	$tBalance = $this->deposit;
        	// if 1 pair selected use appropriate query
        	if(count($selPairs)==1) $pair_id = $selPairs[0];

			$query_pair = "SELECT * FROM vfa_forecast WHERE BeginTime>='$date_from' AND BeginTime<='$date_to' AND TradeID='$pair_id' ORDER BY EndTime asc";
			$query_all = "SELECT * FROM vfa_forecast WHERE BeginTime>='$date_from' AND BeginTime<='$date_to' ORDER BY EndTime asc";

			if ($pair_id) $query = $query_pair;
			else $query = $query_all;

			// add start values
   			//$this->graphArrDetailed['data']['date'][] = 1000000000;
            //$this->graphArrDetailed['data']['balance'][] = $this->deposit;

            //$this->db->debug = true;
			try {

	          		$rs = $this->db->Execute($query);
		           if ($rs){
		           		$cnter = 0;
						while (!$rs->EOF) {
			////////////////////////////////////////////////////////////////////////
      		// process data only for selected pairs and closed forecasts (ClosePrice not null)
			for ($s=0;$s<count($this->trades);$s++){
				if($rs->fields['TradeID']==$this->trades[$s] && $rs->fields['ClosePrice']!=null){

                            $currMonth = date("M Y",$rs->fields['BeginTime']);
                            $this->endMonth = $currMonth;
							$fcastsItem[$cnter]['date'] = date("M Y",$rs->fields['BeginTime']);

       						//-----------------------------------------------------------------------------
                            // set parametersfor each forecast (depending on fa_trades & fa_forecast & form parameters)
                            for($z=0; $z<count($this->pairsArr); $z++){
                            	if($this->pairsArr[$z]['TradeID']==$rs->fields['TradeID']){
	                               $fcastsItem[$cnter]['TradeID'] = $this->pairsArr[$z]['TradeID'];
	                               $fcastsItem[$cnter]['pUSD'] = $this->pairsArr[$z]['pUSD'];
	                               $fcastsItem[$cnter]['caption'] = $this->pairsArr[$z]['Pair'];
	                               $fcastsItem[$cnter]['Spread'] = $this->pairsArr[$z]['Spread'];
	                               $fcastsItem[$cnter]['pipSize'] = $this->pairsArr[$z]['pipSize'];
	                               //$fcastsItem[$cnter]['slippage'] = $this->slippage*$this->pairsArr[$z]['pipSize'];
	                               $fcastsItem[$cnter]['slippage'] = $this->slippage;
                               }
                            }

                            $fcastsItem[$cnter]['beginPrice'] = $rs->fields['BeginPrice'];
							$fcastsItem[$cnter]['closePrice'] = $rs->fields['ClosePrice'];
							$fcastsItem[$cnter]['side'] = $rs->fields['Side'];

                            //-----------------------------------------------------------------------------
                            // set shorter vars for comfort calculations
                            $vBegin = $fcastsItem[$cnter]['beginPrice'];
                            $vClose = $fcastsItem[$cnter]['closePrice'];
                            $vPip = $fcastsItem[$cnter]['pipSize'];
                            $vSlippage = $fcastsItem[$cnter]['slippage'];
                            $vSpread = $fcastsItem[$cnter]['Spread'];

                              //-----------------------------------------------------------------------------
                             // check if forecast for Sale / Buy
                             if ($fcastsItem[$cnter]['side']==0){
                             	$fcastsItem[$cnter]['pips'] = ($vClose - $vBegin)/$vPip - ($vSpread + $vSlippage);

                             	// check if USD is first / second currency
                             	if ($fcastsItem[$cnter]['pUSD']==1) {
                            		$fcastsItem[$cnter]['profit'] = $this->contract * ( ($vClose - $vBegin) - $vPip*($vSpread + $vSlippage) );
                            	} else {
                            		$fcastsItem[$cnter]['profit'] = $this->contract * ( (($vClose - $vBegin) - $vPip*($vSpread + $vSlippage))/$vClose );
                            	}
                             } else{
                             	$fcastsItem[$cnter]['pips'] = ($vBegin - $vClose)/$vPip - ($vSpread + $vSlippage);
                             	if ($fcastsItem[$cnter]['pUSD']==1) {
                            		$fcastsItem[$cnter]['profit'] = $this->contract * ( ($vBegin - $vClose) - $vPip*($vSpread + $vSlippage) );
                            	} else {
                            		$fcastsItem[$cnter]['profit'] = $this->contract * ( (($vBegin - $vClose) - $vPip*($vSpread + $vSlippage))/$vClose );         }
                             }

                            //---------------------------------------------------------------------------------

                            if ($fcastsItem[$cnter]['profit']>=0) $this->winTrades++;
                            else $this->lossTrades++;

                            $currBalance = $currBalance + round($fcastsItem[$cnter]['profit']);
							$fcastsItem[$cnter]['balance'] = $currBalance;

                            // get balaces for all previous forecasts
                            $balanceArr[] = $fcastsItem[$cnter-1]['balance'];
                            $fcastsItem[$cnter]['diffBalance'] = $fcastsItem[$cnter]['balance']-max($balanceArr);

                            if (!$this->tDdown && $fcastsItem[$cnter]['diffBalance']<0)
                            	$this->tDdown = $fcastsItem[$cnter]['diffBalance'];
                            else if ($this->tDdown && $fcastsItem[$cnter]['diffBalance']<$this->tDdown && $fcastsItem[$cnter]['diffBalance']<0)
                            	$this->tDdown = $fcastsItem[$cnter]['diffBalance'];


                            // check if balance is MAX for curr month
							if ($fcastsItem[$cnter]['balance'] > $fcastsItem[$cnter-1]['balance'])
								$maxbalance = $fcastsItem[$cnter]['balance'];



							//-----------------------------------------------------------------------------
                            // fill array for detailed graph drawing
                            // add first value to array for graph
                            if(count( $this->graphArrDetailed['data']['date'])==0){
                             	$this->graphArrDetailed['data']['date'][] = $rs->fields['BeginTime']-1;
                            	$this->graphArrDetailed['data']['balance'][] = $this->deposit;
                            }


                            $this->graphArrDetailed['data']['date'][] = $rs->fields['BeginTime'];
                            $this->graphArrDetailed['data']['balance'][] = $fcastsItem[$cnter]['balance'];

                            //-----------------------------------------------------------------------------
                            // count monthly totals
                            if (!array_key_exists($currMonth,$statsArr)){
	                            $statsArr[$currMonth] = array(
	                            	'date' => $currMonth,
	                            	'pips' => round($fcastsItem[$cnter]['pips']),
	                            	'profit' => round($fcastsItem[$cnter]['profit']),
	                            	'balance' => $this->balance + round($fcastsItem[$cnter]['profit']),
	                            	'tbalance' => round($fcastsItem[$cnter]['balance']),
	                            	'maxbalance' => $maxbalance
	                            );
	      					}
	      					else {
                                 $statsArr[$currMonth]['pips'] = $statsArr[$currMonth]['pips']+round($fcastsItem[$cnter]['pips']);
                                 $statsArr[$currMonth]['profit'] = $statsArr[$currMonth]['profit']+round($fcastsItem[$cnter]['profit']);
                                 $statsArr[$currMonth]['balance'] = $statsArr[$currMonth]['balance']+round($fcastsItem[$cnter]['profit']);
                                 $statsArr[$currMonth]['tbalance'] = $fcastsItem[$cnter]['balance'];
                                 $statsArr[$currMonth]['maxbalance'] = $maxbalance;
	      					}

                            // count overall totals
                            $tPips = $tPips + round($fcastsItem[$cnter]['pips']);
        					$tProfit = $tProfit + round($fcastsItem[$cnter]['profit']);
        					$tBalance = $tBalance + round($fcastsItem[$cnter]['profit']);


             	} // end process data only for selected pairs
			}

                            $cnter++;
					        $rs->MoveNext();
			//////////////////////////////////////////////////////////////////////////
						}

					}

	         } catch(exception $e) {
	            if (true == $this->db->debug ) {
	              adodb_pr($e);
	              $e = adodb_backtrace($e->trace);
	            }
	            die('DB Error: '.$e->sql);
	         }

             $this->fcastsArr = $fcastsItem;
             $this->statsArr = $statsArr;

          	$this->tPips = $tPips;
     		$this->tProfit = $tProfit;
     		$this->tBalance = $tBalance;
     		$this->test = count($selPairs);

			return true;
      	}

		function getYears() {
        	$arrYear = array();
			$sYear = 2006;
			$cYear = date('Y');
			$this->dDate['currYear'] = $cYear;
			$this->dDate['currMonth'] = $cYear = date('n');
			$this->dDate['startYear'] = $sYear;

			for ($i=$sYear;$i<=$cYear;$i++) $arrYear[] = $i;
			return $arrYear;
      	}


       function fillGraphArrMonth($start_date) {
            $this->graphArr['data'] = array();
            $this->graphArr['data']['date'][] = $start_date;
            $this->graphArr['data']['balance'][] = floatval($this->deposit);
              foreach($this->statsArr as $month=>$record){
                  $month = strtotime($month);
                $this->graphArr['data']['date'][] = mktime(23,59,59,date("m",$month)+1,00,date("Y",$month));
                $this->graphArr['data']['balance'][] = floatval($record['tbalance']);
              }
            return true;
       }


       function fillGraphArrWeek($start_date){
       		$week;
       		$year;

       		$ArrWeekTime = array();
       		$ArrWeekBalance = array();
            $this->graphArrWeek['data']['date'][] = $start_date;
            $this->graphArrWeek['data']['balance'][] = floatval($this->deposit);
            $ArrWeekTime[] = $start_date;
       		$ArrWeekBalance[] = $this->deposit;
              $cntr = 0;
            foreach($this->graphArrDetailed['data']['date'] as $record){
                /*
            	$week = date("W",$record);
            	$year = date("Y",$record);
            	$aIndex = intval($week)."-".$year;

                   	$ArrWeekTime[$aIndex] = $record;
            		$ArrWeekBalance[$aIndex] = $this->graphArrDetailed['data']['balance'][$cntr];

                $cntr++;
                */
                $aIndex = DateConvert::Date('YW',$record);//adodb_date('YW',$record);
                $ArrWeekTime[$aIndex] = $record;
            	$ArrWeekBalance[$aIndex] = $this->graphArrDetailed['data']['balance'][$cntr];
                $cntr++;
            }
            $NewArrWeekTime = array();
            foreach($ArrWeekTime as $item_name => $item_value) $NewArrWeekTime[] = $item_value;

            $NewArrWeekBalance = array();
            foreach($ArrWeekBalance as $item_name => $item_value) $NewArrWeekBalance[] = $item_value;

            $this->graphArrWeek['data']['date'] = $NewArrWeekTime;
            $this->graphArrWeek['data']['balance'] = $NewArrWeekBalance;
            return true;
       }



       function formDate($y_f,$m_f,$y_t,$m_t) {
        	$lastDay;
        	for($i=28; checkdate($m_t, $i, $y_t); $i++) {
        		$lastDay = $i;
        	}
        	$this->timeRange = array(strtotime("$y_f-$m_f-01"),strtotime("$y_t-$m_t-$lastDay 23:59:59"));
			//return $timeRange;
      	}

		function separate1000($arr) {
        	for($i=0; $i<count($arr); $i++) {
        		$arr[$i]['tbalance'] = number_format($arr[$i]['tbalance']);
        	}
			return $arr;
      	}
      	function calculate($beginPrice,$closePrice,$spread,$priceUsd,$pipSize) {
        	$calcResult = array();
        	$contractSize = 100000;
        	$slippage = 3;

			$calcResult['pips'] = 'pps';
			$calcResult['profit'] = $contractSize*($closePrice - $beginPrice);
			$calcResult['balance'] = $beginPrice;


			return $calcResult;
      	}

      	function calculateTotals() {
      		$totalStats = array();

			$DDprefix = "$";
			$DDown = $this->tDdown;

			// in progress.....
			//if ($DDown<0) $DDprefix = "$";
			//else $DDprefix = "$";

            $totalStats['months'] = count($this->statsArr);
            $this->tARR = ((($this->tProfit / $this->deposit) / ($totalStats['months']) * 12))*100;
      		$totalStats['pips'] = $this->tPips;
      		$totalStats['profit'] = number_format($this->tProfit);
        	$totalStats['balance'] = number_format($this->tBalance);
            $totalStats['arr'] = round($this->tARR,2);
            $totalStats['ddown'] = $DDprefix.number_format(intval($DDown));
            $totalStats['wTrades'] = $this->winTrades;
			$totalStats['wTrades1'] = round( (100/($this->winTrades + $this->lossTrades))*$this->winTrades );
			$totalStats['lTrades'] = $this->lossTrades;
			$totalStats['lTrades1'] = 100 - $totalStats['wTrades1'];

			return $totalStats;
      	}

      	function Render($Staff) {
      		$Calc = new objTemplate();
      		//$Calc->Assign('test',$this->getForecastData($this->timeRange[0],$this->timeRange[1],'2400304'));
      		$Calc->Assign('dDate',$this->dDate);
        	$Calc->Assign('pairs',$this->getPairs());
        	$Calc->Assign('spreads',array(0,1,2,3,4,5,6));
        	$Calc->Assign('UserPairs',$Staff->UserPairs());
        	$Calc->Assign('pairs_num',count($Staff->UserPairs()));
         	$Calc->Assign_by_ref('calc',$this);
            return $Calc->Fetch('_form_calc.tpl');
      	}

} // calculator

    function getCalcResult($aFormValues,$pairID) {

         $tabContent = '';

         $calc = new objCalculator();
         $calc->formDate($aFormValues['year_from'],$aFormValues['month_from'],$aFormValues['year_to'],$aFormValues['month_to']);
         for($q=0;$q<count($aFormValues['data_trades']);$q++) $calc->spreadArr[] = $aFormValues[$aFormValues['data_trades'][$q]];
         $calc->getPairs();
         $calc->slippage = $aFormValues['data_slippage'];
         $calc->contract = $aFormValues['data_contract'];
         $calc->balance = $aFormValues['data_balance'];
         $calc->deposit = $aFormValues['data_deposit'];
         $calc->trades = $aFormValues['data_trades'];

         // show results for all pairs or for one
         if ($pairID==1)
         	$calc->getForecastData($calc->timeRange[0],$calc->timeRange[1],false,$aFormValues['data_trades']);
         else
         	$calc->getForecastData($calc->timeRange[0],$calc->timeRange[1],$pairID,array($pairID));

		 $calc->fillGraphArrMonth($calc->timeRange[0]);
		 $calc->fillGraphArrWeek($calc->timeRange[0]);
   		global $config;
         $Session = new objSession($config['app_id']);
   		 $Session->put('CalculatorResult',$calc->graphArr);
   		 $Session->put('CalculatorResultFcasts',$calc->graphArrDetailed);
   		 $Session->put('CalculatorResultWeek',$calc->graphArrWeek);

         $cTemplate = new objTemplate();
    	 //$cTemplate->Assign('fcasts',$calc->fcastsArr);
    	 $cTemplate->Assign('fdetails',$calc->graphArrDetailed);
    	 $cTemplate->Assign('statsArr',$calc->statsArr);
    	 $cTemplate->Assign('pairs',$calc->pairsArr);
    	 $cTemplate->Assign('totals',$calc->calculateTotals());
    	 $cTemplate->Assign('selPairs',$aFormValues['data_trades']);
    	 $cTemplate->Assign('currPair',$pairID);
    	 $cTemplate->Assign('slippage',$calc->slippage);
    	 $cTemplate->Assign('spreads',$calc->spreadArr);
    	 $cTemplate->Assign('detalisation',$aFormValues['detalisation']);
    	 $cTemplate->Assign('test',time());
    	 $cTemplate->Assign('weeks',$Session->get('CalculatorResultWeek'));
    	 $cTemplate->Assign('deposit',number_format($calc->deposit));
         $tabContent .= $cTemplate->Fetch('_form_calc_result.tpl');
         //----------------------------------------------------------------------
         $objResponse = new xajaxResponse();
		 $objResponse->addAssign("calcResult","innerHTML", $tabContent);
         //---------------------------------------------------------------------
         unset($calc);
         unset($aFormValues);
         unset($tabContent);

         //----------------------------------------------------------------------

         return $objResponse;
    }//getCalcResult



?>
